#lang racket

(require racket/match)

;; scope sets part

(require "utilities.scm")
(require "box.scm")
(require "parser.scm")
(require "syntax-object.scm")
(require "resolve.scm")
(require "environment.scm")
(require "interpret.scm")
(require "scope-sets.scm")


;; sans part

(require "util/utils.scm")
(require "pass-tag.scm")
(require "pass-scope.scm")
(require "pass-letrec.scm")
(require "pass-hoist.scm")
(require "pass-denest.scm")
(require "pass-temps.scm")
;;(require "pass-mark-calls.scm")
(require "pass-flat.scm")
(require "pass-delabel.scm")
(require "pass-labels.scm")
(require "pass-csans.scm")
(require "opt-known-calls.scm")
(require "interpreter.scm")

(require racket/system)

(define args (vector->list (current-command-line-arguments)))

(define filename (car args))

;;; scheme builtins
;;

(define-syntax define-builtins
  (syntax-rules ()
    ((define-builtins builtins <name> ...)
     (define builtins
       `((<name> . ,(box <name>)) ...)))))

(define-builtins builtins
  cons car cdr list null?
  box box-value set-box-value!
  = eq? equal? not
  + - * /
  display newline print
  error

  ;; predicates from R5RS  
  boolean?
  pair?
  symbol?
  number? even? odd?
  char?
  string?
  vector?
  procedure?

  ;; syntax-object manipulation
  syx syx-id?
  syn-car syn-cdr
  identifier-equal?
  )


(with-output-to-file "csans/csans.c"
  (lambda ()
    (let* ((prg (parse-file filename))
	   (cod (syn->datum (resolve-program prg builtins))))
      (pass-csans (pass-labels (pass-flat (pass-temps (pass-denest (opt-known-calls (pass-hoist (pass-letrec (pass-scope (pass-tag cod))))))))) #f)))
  #:exists 'truncate)

(system* "/bin/sh" "csans-compile-and-run.sh")
